package com.mystudy.javalambdastudy.function;

import java.text.ParseException;
import java.util.Comparator;
import java.util.function.*;

/**
 * TODO: {@link Function} 函数使用 对单个参数进行操作
 * 1.apply方法：将此函数应用于给定的参数。可以理解为为传入的参数执行指定的操作
 * 2.compose方法： 就是对apply方法的复用，就是多个Function函数的调用，
 * 3.andThen方法： 跟compose方法调用顺序相反
 * todo: {@link BiFunction} 对两个参数进行操作
 * 1.apply方法: 跟Function中一样
 * 2.andThen方法: 跟Function中一样
 * todo: {@link Predicate} 对参数进行逻辑校验
 * 1.test方法: 跟Function中apply方法一样
 * todo: {@link Supplier} 不接收参数，只返回结果
 * 1.get方法： 不接收参数，之返回结果，返回结果自己定义
 * todo：{@link BinaryOperator} 自定义比较方式，返回最大/最小的那个指
 *
 * @author acy
 * @since 2019/04/28 14:09
 */
public class Java8FunctionTest {
	//apply方法
	public int compute(int a, Function<Integer, Integer> function) {
		return function.apply(a);
	}

	//compose方法  先function2 --->后function1
	public int composeTest(int a, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
		return function1.compose(function2).apply(a);
	}

	//andThen方法  先function1 --->后function2
	public int andThenTest(int a, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
		return function1.andThen(function2).apply(a);
	}

	//BiFunction 对两个参数进行处理
	public int biFunctionTest(int a, int b, BiFunction<Integer, Integer, Integer> biFunction) {
		return biFunction.apply(a, b);
	}

	//BiFunction的andThen  biFunction --->后function
	public int biFunctionAndThenTest(int a, int b, BiFunction<Integer, Integer, Integer> biFunction, Function<Integer, Integer> function) {
		return biFunction.andThen(function).apply(a, b);
	}

	//Predicate的test方法
	public boolean predicateTest(int a, Predicate<Integer> predicate) {
		return predicate.test(a);
	}

	//Supplier的get方法
	public int supplierTest(Supplier<Integer> supplier) {
		return supplier.get();
	}

	//
	public int binaryOperatorTest(Integer a, Integer b, Comparator<Integer> comparator) {
		return BinaryOperator.minBy(comparator).apply(a, b);
	}

	public static void main(String[] args) throws ParseException {
		Java8FunctionTest functionTest = new Java8FunctionTest();
		//这里可以吧lambda表达式看成是一种行为，因为compute方法中的apply方法并不清楚是什么操作，而这里我们定义了具体的行为value + 2
		System.out.println(functionTest.compute(1, value -> value + 2));
		//这里我们直接定义好一种行为，然后传递到compute中，跟上面的形式是一样的
		Function<Integer, Integer> function = value -> value + 2;
		System.out.println(functionTest.compute(1, function));
		//compose方法---->6
		System.out.println(functionTest.composeTest(1, value -> value * 2, value -> value + 2));
		//andThen方法---->4
		System.out.println(functionTest.andThenTest(1, value -> value * 2, value -> value + 2));
		//biFunction
		System.out.println(functionTest.biFunctionTest(2, 4, (value1, value2) -> value1 + value2));
		//BiFunction的andThen
		System.out.println(functionTest.biFunctionAndThenTest(2, 4, (value1, value2) -> value1 + value2, value1 -> value1 * 3));
		//Predicate的test
		System.out.println(functionTest.predicateTest(2, value1 -> value1 > 1));
		//supplier的test
		System.out.println(functionTest.supplierTest(() -> 1));
		//binaryOperator
		System.out.println(functionTest.binaryOperatorTest(1, 2, (value1, value2) -> value1 - value2));
		/**
		 * String::toUpperCase 方法引用中的一种。
		 * {@link Function}函数的apply方法需要一个传入的参数，而{@link String}的toUpperCase方法调用不能直接使用类调用的
		 * 需要使用一个{@link String}类型的参数进行调用的，所以可以将String::toUpperCase理解为，将一个string类型的参数
		 * 传入了Function的apply方法中，在apply方法中调用调用了toUpperCase方法
		 */
		/*Function<String, String> function = String::toUpperCase;
		System.out.println(function.getClass().getInterfaces()[0]);*/
	}


}
